package org.iabako.server.controller.timer.business;

import org.apache.log4j.Logger;
import org.iabako.server.dao.business.SaleDAO;
import org.iabako.server.tools.ServerTools;
import org.iabako.shared.entity.business.Installment;
import org.iabako.shared.entity.business.InstallmentsDefinition;
import org.iabako.shared.entity.business.Sale;
import org.iabako.shared.entity.user.Enterprise;
import org.iabako.shared.iservice.business.SaleService;
import org.iabako.shared.iservice.user.UserService;
import org.iabako.shared.tools.GenericTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by jose on 19/11/14.
 */

@Controller
public class CreatePastInstallmentsControllerTimer {

    static Logger log = Logger.getLogger(CreatePastInstallmentsControllerTimer.class.getName());

    @Autowired
    private SaleDAO saleDAO;
    @Autowired
    private SaleService saleService;
    @Autowired
    private UserService userService;


    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    //Every day at 00:10 AM
    @Scheduled(cron = "0 10 0 * * ?")
    public void action() throws Exception {
        log.info("Executing CreatePastInstallmentsControllerTimer...");
        try {
            List<InstallmentsDefinition> installmentDefinitions = saleDAO.getExpiredUndefinedInstallments();
            log.info("Number of expired undefined INSTALLMENTS : "
                    + (installmentDefinitions == null ? 0 : installmentDefinitions.size()));

            if (GenericTools.isEmpty(installmentDefinitions)) {
                return;
            }

            Set<Enterprise> enterpriseSet = new HashSet<Enterprise>();
            for (InstallmentsDefinition iDef : installmentDefinitions) {

                Sale sale = iDef.getSale();

                Installment installment = new Installment();
                installment.setDate(iDef.getNextUndefinedInstallment());
                installment.setAmount(iDef.getInstallmentsPeriodicalPrice());
                installment.setSale(sale);

                sale.getInstallments().add(installment);

                //Calculate NEW next undefined installment date
                iDef.setNextUndefinedInstallment(iDef.addNToDate(new ServerTools(), iDef.getNextUndefinedInstallment(),
                        iDef.getInstallmentsPeriodicalFrequency(), iDef.getInstallmentsPeriodicalFrequencyN()));

                //this method merge Sale with installments cascading
                //(and without other business tasks, ex: memorize lastModification)
                saleService.calculateStatusAndSave(sale, false);
                enterpriseSet.add(sale.getEnterprise());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }
}
